<script lang="ts" setup>
/**
 * @ClassName BaseIcon
 * @Description 基础图标，支持el-icon图标库组件、iconfont等图标
 * @Author xuyizhuo
 * @Date 2024/12/8 22:01
 * @example
 *      <BaseIcon name="icon_calendar" />
 *      <BaseIcon name="图标名称" size="20" />
 */
import { elIconNames } from '@/utils/icon'
import type { Component } from 'vue'

/** 图标组件参数 */
export interface IconProps {
    /** 图标的颜色 */
    color?: string
    /** 图标的大小 */
    size?: string | number
    /** 所使用的图标名称 */
    name: string | Component
    /** 图标的样式 */
    style?: AnyObject // Record<string, any>
}

withDefaults(defineProps<IconProps>(), {
    size: 16,
    color: '',
    style: () => ({}),
})
</script>

<template>
    <!--1、Element plus 的图标-->
    <el-icon
        v-if="elIconNames.includes(name as string)"
        :color="color"
        :size="Number(size)"
        :style="{
            ...(style || {}),
        }"
        class="base-icon"
    >
        <component :is="name" />
    </el-icon>
    <!--2、iconfont图标支持-->
    <i
        v-else-if="typeof name === 'string'"
        :style="{
            fontSize: (size || 16) + 'px',
            ...(style || {}),
        }"
        class="base-icon"
    >
        <svg
            :style="{
                color,
            }"
        >
            <use :xlink:href="`#icon-${name}`" />
        </svg>
    </i>
    <!--3、普通组件-->
    <i
        v-else
        :style="{
            fontSize: (size || 16) + 'px',
            ...(style || {}),
        }"
        class="base-icon"
    >
        <component
            :is="name"
            :style="{
                color,
            }"
        />
    </i>
</template>

<style lang="scss" scoped>
.base-icon {
    display: inline-flex;
    position: relative;
    justify-content: center;
    align-items: center;
    width: 1em;
    height: 1em;
    line-height: 1em;
    fill: currentColor;

    svg {
        width: 1em;
        height: 1em;
    }
}
</style>
